package com.jingdianjichi.auth.application.context;

/**
 * 登录用户信息上下文持有者
 * 
 * 使用ThreadLocal存储当前线程的用户信息，确保线程安全。
 * 每个HTTP请求在独立的线程中处理，因此可以安全地使用ThreadLocal
 * 来存储和获取当前请求的用户信息。
 * 
 * 主要功能：
 * 1. 存储当前登录用户ID到ThreadLocal
 * 2. 提供线程安全的用户信息获取方法
 * 3. 提供清理方法防止内存泄漏
 * 
 * 使用场景：
 * - 在拦截器中设置用户信息
 * - 在业务代码中获取当前用户信息
 * - 在请求结束时清理用户信息
 * 
 * 注意事项：
 * - 必须在请求结束时调用clear()方法
 * - 在异步处理中需要手动传递用户信息
 * - 不要在ThreadLocal中存储大对象
 *
 * @author: CodeBuddy
 * @date: 2025/9/19
 */
public class LoginContextHolder {
    
    /**
     * ThreadLocal存储当前登录用户ID
     * 每个线程都有独立的用户信息副本，确保线程安全
     */
    private static final ThreadLocal<String> LOGIN_ID = new ThreadLocal<>();
    
    /**
     * 设置当前登录用户ID
     * 
     * 通常在请求拦截器中调用，将从请求头中提取的用户ID
     * 存储到当前线程的ThreadLocal中。
     * 
     * @param loginId 用户ID，不能为null
     */
    public static void set(String loginId) {
        LOGIN_ID.set(loginId);
    }
    
    /**
     * 获取当前登录用户ID
     * 
     * 从当前线程的ThreadLocal中获取用户ID。
     * 如果当前线程没有设置用户信息，返回null。
     * 
     * @return 用户ID，如果未设置则返回null
     */
    public static String getLoginId() {
        return LOGIN_ID.get();
    }
    
    /**
     * 检查当前线程是否设置了用户信息
     * 
     * @return true-已设置用户信息，false-未设置
     */
    public static boolean hasLoginId() {
        return LOGIN_ID.get() != null;
    }
    
    /**
     * 清除当前线程的用户信息
     * 
     * 重要：请求处理完成后必须调用此方法，避免内存泄漏。
     * 在Web应用中，线程通常会被线程池复用，如果不清理ThreadLocal，
     * 会导致用户信息在不同请求间泄漏。
     * 
     * 调用时机：
     * - 在拦截器的afterCompletion方法中
     * - 在异常处理器中
     * - 在finally块中
     */
    public static void clear() {
        LOGIN_ID.remove();
    }
}